function [textinfile, starts, ends, lnum] = asciiread(filename, linedelim)
% asciiread  - reads a textfile into one char array
%
% FORMAT:       textinfile = asciiread(filename [, linedelim])
%
% Input Fields:
%
%       filename    name to a file, preferably absolute path
%       linedelim   optional char array with line delimiter
%
% Output will be delimited as is written in the file. Hence, an
% optional line delimiter can be given...
%
% See also asciiwrite

% Version:  v0.8a
% Build:    9102317
% Date:     Oct-23 2009, 7:09 PM CEST
% Author:   Jochen Weber, SCAN Unit, Columbia University, NYC, NY, USA
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

% argument check
if nargin < 1 || ...
   ~ischar(filename) || ...
    isempty(filename)
    error( ...
        'BVQXtools:BadArgument',...
        'Bad argument given. Try ''help %s''.',...
        mfilename ...
    );
end

% open file (check readability)
filename = filename(:)';
fp = fopen(filename, 'r');
if fp < 1
    error( ...
        'BVQXtools:FileNotReadable',...
        'File not readable: %s',...
        filename ...
    );
end

% read file contents
textinfile = fread(fp, [1, Inf], 'uchar=>char');
fclose(fp);

% detect linedelim if not given
if (nargin > 1 && ...
     ischar(linedelim)) || ...
    nargout > 2

    % get first 16kB (if that many)
    arp  = textinfile(1:min(16384, length(textinfile)));

    % find Mac, Windows and Linux <RETURN> codes
    LfCr = strfind(arp, char([10, 13]));
    CrLf = strfind(arp, char([13, 10]));
    Lf   = strfind(arp, char(10));
    Cr   = strfind(arp, char(13));

    % is there a combined code (not unique, happens with blank lines!)
    if ~isempty(LfCr)

        % is there ONLY ONE type of combined code
        if isempty(CrLf)

            % then we know it
            srcld = char([10, 13]);

        % otherwise
        else

            % decide according to the number of matches
            if length(LfCr) > length(CrLf)
                srcld = char([10, 13]);
            else
                srcld = char([13, 10]);
            end
        end

    % if ONLY THE OTHER combination is found
    elseif ~isempty(CrLf)
        srcld = char([13, 10]);

    % only Linux linefeeds
    elseif ~isempty(Lf)
        srcld = char(10);

    % only carriage returns (RARE!)
    elseif ~isempty(Cr)
        srcld = char(13);

    % no <RETURN> codes, delimiter must then be given externally!
    else
        error( ...
            'BVQXtools:AutoDetectFailed', ...
            'Could not determine line delimiter in source.' ...
        );
    end
end

% replace line delimiter before continuing
if nargin > 1 && ...
    ischar(linedelim)
    textinfile = strrep(textinfile, srcld, linedelim);
    srcld = linedelim;
end

% given second output argument if needed
if nargout > 2
    lsrcld = length(srcld);
    ltext = length(textinfile);
    if lsrcld == 1
        ends = find(textinfile == srcld);
    else
        ends = strfind(textinfile, srcld);
    end
    if (ends(end) + lsrcld) < ltext
        ends(end + 1) = ltext + 1;
    end
    starts = [1 (ends(1:end-1) + lsrcld)];
    ends = ends - 1;
    lnum = length(starts);
end
